/*
 * Created: Author: Aléx Carvalho / Date: Feb 25, 2015
 * 
 * Changed: $Author: ac280593@gmail.com $ / $Date: 2015-06-11 01:28:43 -0300 (Thu, 11 Jun 2015) $
 */
package com.cpm.entities;

import com.cpm.entities.converters.FamilyPersistenceConverter;
import com.cpm.entities.id.IntegerId;
import com.cpm.entities.types.Family;
import com.cpm.wrapper.Performance;
import com.cpm.wrapper.Position;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Convert;
import javax.persistence.FetchType;
import javax.persistence.ManyToOne;
import javax.persistence.MappedSuperclass;
import javax.persistence.OneToOne;

@MappedSuperclass
public abstract class Node<T> extends IntegerId implements Identity<T> {

    @Column(nullable = false)
    protected Integer parentId;

    protected Performance performance;

    protected Position position;

    @Column(nullable = false)
    @Convert(converter = FamilyPersistenceConverter.class)
    protected Family parentFamily;

    @ManyToOne(optional = false)
    protected StrategicPlan strategicPlan;

    @ManyToOne(optional = false)
    protected User responsible;

    @Column(length = 200, nullable = false)
    protected String name;

    // TODO: Corrigir para carregar em lazy
    @OneToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
    protected Information information;

    public Node() {
    }

    @Override
    public abstract T clone();
    
    public void decrementPosition() {
        position = position.decrement();
    }

    public void incrementPosition() {
        position = position.increment();
    }

    public Position getPosition() {
        return new Position(position);
    }

    public void setPosition(Position position) {
        this.position = position;
    }

    public void setParentId(Integer parentId) {
        this.parentId = parentId;
    }

    public Integer getParentId() {
        return parentId;
    }

    public Family getParentFamily() {
        return parentFamily;
    }

    public void setParentFamily(Family parentFamily) {
        this.parentFamily = parentFamily;
    }

    public Performance getPerformance() {
        return performance;
    }

    public void setPerformance(Performance performance) {
        this.performance = performance;
    }

    public User getResponsible() {
        return responsible;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
    
    public Information getInformation() {
        return information;
    }

    public void setInformation(Information info) {
        if (information == null) {
            this.information = info;
        }
        else {
            this.information.setValue(info.getValue());
        }
    }
    
    public boolean isIndicator(){
        return getFamily() == Family.INDICATOR;
    }
    
    public boolean isFolder(){
        return getFamily() == Family.FOLDER;
    }
    
    @Override
    public int hashCode() {
        return getId().hashCode();
    }

    @Override
    public boolean equals(Object obj) {
        if (obj instanceof Node) {

            Node node = (Node) obj;

            return super.equals(obj) && getFamily() == node.getFamily();
        }

        return false;
    }
}
